package com.ccteam.shared.data.user

import com.ccteam.model.Resource
import com.ccteam.model.setting.SettingInfoDTO
import com.ccteam.model.setting.SettingInfoEditDTO
import com.ccteam.model.setting.SettingInfoVO
import com.ccteam.model.user.*
import com.ccteam.network.ApiResult
import com.ccteam.network.ResultVO
import com.ccteam.shared.api.UserDataSource
import com.ccteam.shared.data.BaseBoundResource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import javax.inject.Inject
import javax.inject.Singleton

/**
 * @author Xiaoc
 * @since 2021/3/19
 */
@Singleton
class UserRepository @Inject constructor(
    private val userDataSource: UserDataSource
) {

    private val userInfo = mutableMapOf<String,List<UserVO>>()

    fun getUserInfo(id: String): Flow<Resource<List<UserVO>>>{
        return object: BaseBoundResource<List<UserVO>, ResultVO<UserVO>>(){
            override fun loadFromDbOrMemory(): Flow<List<UserVO>> {
                return flowOf(userInfo[id] ?: emptyList())
            }

            override suspend fun saveNetworkResult(item: ResultVO<UserVO>) {
                val result = if(item.data != null){
                    listOf(item.data!!)
                } else {
                    emptyList()
                }
                userInfo[id] = result
            }

            override fun shouldFetch(data: List<UserVO>?): Boolean {
                return true
            }

            override suspend fun fetchFromNetwork(): ApiResult<ResultVO<UserVO>> {
                return userDataSource.getUserInfo(id)
            }

        }.asFlow()
    }

    suspend fun editUserInfo(token: String,userDTO: UserNoPasswordDTO): ApiResult<ResultVO<Nothing>>{
        return userDataSource.editUserInfo(token,userDTO)
    }

    suspend fun editUserPassword(token: String,userDTO: UserPasswordVerifyDTO): ApiResult<ResultVO<Nothing>>{
        return userDataSource.editUserPassword(token,userDTO)
    }

    suspend fun getDetailUserInfo(token: String): ApiResult<ResultVO<UserDetailVO>>{
        return userDataSource.getUserDetailInfo(token)
    }

    suspend fun verifyOldPhone(token: String,phoneVerifyDTO: UserPhoneVerifyDTO): ApiResult<ResultVO<Nothing>>{
        return userDataSource.verifyOldPhone(token,phoneVerifyDTO)
    }

    suspend fun verifyNewPhone(token: String,phoneVerifyDTO: UserPhoneVerifyDTO): ApiResult<ResultVO<Nothing>>{
        return userDataSource.verifyNewPhone(token,phoneVerifyDTO)
    }

    suspend fun createUserSettingInfo(token: String,
                                      settingInfo: SettingInfoDTO
    ): ApiResult<ResultVO<Nothing>>{
        return userDataSource.createUserSettingInfo(token,settingInfo)
    }

    suspend fun editUserSettingInfo(token: String,
                                      settingInfo: SettingInfoEditDTO
    ): ApiResult<ResultVO<Nothing>>{
        return userDataSource.editUserSettingInfo(token,settingInfo)
    }

    suspend fun getUserSettingInfo(token: String,
                                   userId: String): ApiResult<ResultVO<SettingInfoVO>>?{
        return userDataSource.getUserSettingInfo(token,userId)
    }
}